home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 5
/
Aminet 5 - March 1995.iso
/
Aminet
/
util
/
time
/
PictureClock.lha
/
PictureClock
/
PictureClock.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-22
|
26KB
|
939 lines
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/devices.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <dos/rdargs.h>
#include <dos/dostags.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <intuition/icclass.h>
#include <intuition/pointerclass.h>
#include <graphics/view.h>
#include <devices/timer.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <utility/date.h>
#include <workbench/icon.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <datatypes/soundclass.h>
#include <clib/alib_protos.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/utility_protos.h>
#include <clib/timer_protos.h>
#include <clib/wb_protos.h>
#include <clib/icon_protos.h>
#include <clib/datatypes_protos.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <math.h>
#define NUMFILES 20
#define MAXFILES 1000
#define NAMESIZE 256
#define SHIFT 0x60
#define MAX_LONG 70000000L
#define MILLION 100000L
#define B_SHOW 0
#define B_RENDER 1
#define B_SWAP 2
#define B_FREE 3
#define TITLE "PictureClock"
#define OKAY "Okay"
#define CANCEL "Cancel"
#define OKCAN "Okay|Cancel"
#define NUM_OPTS 8
const UBYTE VERSION[]="$VER: PictureClock 39.72 (22-08-94)";
UBYTE SoundProcName[]="PictureClock sound daemon";
UBYTE TEMPLATE[]="PICTURE/A,SOUND,WAIT=WAITBETWEENSAMPLES/N,NOSEC/S,NOTICK/S,CONT=CONTINUOUS/S,BESTMODEID/S,SLIM/S";
enum option_identifiers {PICTURE,SOUND,WAIT,NOSEC,NOTICK,CONT,BESTMODEID,SLIM};
struct RDArgs *Arguments;
struct DiskObject *ProgramIcon;
ULONG options[NUM_OPTS];
extern __far struct Custom custom;
extern struct DosLibrary *DOSBase;
extern struct ExecBase *SysBase;
extern struct WBStartup *_WBenchMsg;
struct Library *DataTypesBase;
struct Library *TimerBase;
struct Screen *MyScreen;
struct Window *Front;
struct BitMap *ExtraMap;
struct Process *PictureClock,*Beieraar;
struct ClockData CurrTime;
struct timerequest TimerRequest;
struct MsgPort *TimePort,*InputPort,*BufferPort[2];
Object *Picture,*Sound;
BPTR Handle;
BOOL Workbench;
__chip UWORD AreaData[25];
struct AreaInfo ar_Info;
struct TmpRas ar_Raster;
PLANEPTR TempRaster;
struct DBufInfo *DoubleBuffer;
struct BitMap *BufferMap[4];
struct RastPort RenderPort;
struct InputEvent KeyPress;
struct IOStdReq InputReq;
LONG Beierink,TimeCount;
LONG X,Y,MX,MY,HX,HY;
ULONG GreyPen,WhitePen,BlackPen,RedPen;
LONG Left,Top,Right,Bottom,RadiusY,RadiusX,MiddleX,MiddleY,TopOffset;
LONG tmpX1,tmpX2,tmpY1,tmpY2;
double angle,mangle,hangle,Sec,Min,Hour,HRX,HRY;
double tmpRX,tmpRY;
double HourFactor=0.4,MinFactor=1;
struct TableCol {
ULONG Red,Green,Blue;
};
struct LoadRGB32Table {
UWORD NumCols;
UWORD FirstCol;
struct TableCol Registers[256];
} *Table;
void CleanUp(void)
{
LONG i;
for(i=0; i<2; i++) if (BufferPort[i]) DeleteMsgPort(BufferPort[i]);
if (Arguments) FreeArgs(Arguments);
if (ProgramIcon) FreeDiskObject(ProgramIcon);
if (Front) CloseWindow(Front);
if (ExtraMap) FreeBitMap(ExtraMap);
if (BufferMap[B_FREE]) FreeBitMap(BufferMap[B_FREE]);
if (Workbench) OpenWorkBench();
if (MyScreen) CloseScreen(MyScreen);
if (DoubleBuffer) FreeDBufInfo(DoubleBuffer);
if (TempRaster) FreeRaster(TempRaster,MiddleX,MiddleY);
if (Picture) DisposeDTObject(Picture);
if (Table) FreeMem(Table,sizeof(struct LoadRGB32Table));
if (TimerBase) CloseDevice((struct IORequest *) &TimerRequest);
if (TimePort) DeleteMsgPort(TimePort);
if (InputReq.io_Device) CloseDevice((struct IORequest *) &InputReq);
if (InputPort) DeleteMsgPort(InputPort);
if (Beieraar) Signal((struct Task *) Beieraar,SIGBREAKF_CTRL_C);
if (Sound) DisposeDTObject(Sound);
if (DataTypesBase) CloseLibrary(DataTypesBase);
}
ULONG ExAllDoesntWorkAtAll(BPTR lock, struct FileInfoBlock *fib, UBYTE *Buffer[], ULONG BCount, ULONG AllocSize)
{
struct DataType *dtn;
ULONG Buffer_t=0L;
BPTR FileLock;
UBYTE File[NAMESIZE],INFO[]="#?.info",Pattern[20];
ParsePatternNoCase(INFO,Pattern,20);
while (Buffer_t < BCount && ExNext(lock,fib)) {
if(fib->fib_DirEntryType > 0) continue;
if(MatchPatternNoCase(Pattern,fib->fib_FileName)) continue;
NameFromLock(lock,File,NAMESIZE);
AddPart(File,fib->fib_FileName,NAMESIZE);
if (FileLock=Lock(File,SHARED_LOCK)) {
if (dtn = ObtainDataTypeA (DTST_FILE, (APTR) FileLock, NULL)) {
if (dtn->dtn_Header->dth_GroupID == GID_PICTURE) {
Buffer[Buffer_t]=AllocMem(AllocSize,MEMF_CLEAR);
if (Buffer[Buffer_t]) {
strncpy(Buffer[Buffer_t],File,AllocSize);
Buffer_t++;
}
}
ReleaseDataType (dtn);
}
UnLock (FileLock);
}
}
return(Buffer_t);
}
LONG Message(char *body, char *buttons,...)
{
struct EasyStruct ER={sizeof(struct EasyStruct),0,0,NULL,NULL };
va_list arglist;
ER.es_Title=TITLE" message";
ER.es_TextFormat=body;
ER.es_GadgetFormat=buttons;
va_start(arglist,buttons);
return EasyRequestArgs(Front,&ER,0,(APTR) arglist);
va_end(arglist);
}
void __saveds BeierDeBeier(void)
{
LONG sig;
struct dtTrigger Play;
while (TRUE) {
sig=Wait(SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F);
if (sig & SIGBREAKF_CTRL_C) return;
if (sig & SIGBREAKF_CTRL_F) {
if (TimeCount==0) {
/* Make noise */
Play.MethodID=DTM_TRIGGER;
Play.dtt_GInfo=NULL;
Play.dtt_Function=STM_PLAY;
Play.dtt_Data=NULL;
DoDTMethodA(Sound,NULL,NULL,(Msg) &Play);
Beierink--;
if (options[WAIT] && Beierink)
TimeCount= * ((LONG *) options[WAIT]);
} else TimeCount--;
}
}
}
void DrawArms(void)
{
ULONG Pen;
/* Hour arm */
{
SetAPen(&RenderPort,GreyPen);
tmpX1=(LONG) (sin(((Hour-HourFactor)/12) * 2 * PI) * tmpRX);
tmpY1=(LONG) (cos(((Hour-HourFactor)/12) * 2 * PI) * tmpRY);
tmpX2=(LONG) (sin(((Hour+HourFactor)/12) * 2 * PI) * tmpRX);
tmpY2=(LONG) (cos(((Hour+HourFactor)/12) * 2 * PI) * tmpRY);
AreaMove(&RenderPort,MiddleX,MiddleY);
AreaDraw(&RenderPort,MiddleX+tmpX1,MiddleY-tmpY1);
AreaDraw(&RenderPort,MiddleX+HX,MiddleY-HY);
AreaDraw(&RenderPort,MiddleX+tmpX2,MiddleY-tmpY2);
AreaEnd(&RenderPort);
if (tmpY1 > tmpY2) Pen=WhitePen; else Pen=BlackPen;
if (tmpY1 == tmpY2) {
if (tmpX1 < tmpX2) Pen=WhitePen; else Pen=BlackPen;
}
SetAPen(&RenderPort,Pen);
Move(&RenderPort,MiddleX,MiddleY);
Draw(&RenderPort,MiddleX+tmpX1,MiddleY-tmpY1);
Draw(&RenderPort,MiddleX+HX,MiddleY-HY);
if (Pen == BlackPen) Pen=WhitePen; else Pen=BlackPen;
SetAPen(&RenderPort,Pen);
Draw(&RenderPort,MiddleX+tmpX2,MiddleY-tmpY2);
Draw(&RenderPort,MiddleX,MiddleY);
}
/* Minute arm */
{
SetAPen(&RenderPort,GreyPen);
tmpX1=(LONG) (sin(((Min-MinFactor)/60) * 2 * PI) * HRX);
tmpY1=(LONG) (cos(((Min-MinFactor)/60) * 2 * PI) * HRY);
tmpX2=(LONG) (sin(((Min+MinFactor)/60) * 2 * PI) * HRX);
tmpY2=(LONG) (cos(((Min+MinFactor)/60) * 2 * PI) * HRY);
AreaMove(&RenderPort,MiddleX,MiddleY);
AreaDraw(&RenderPort,MiddleX+tmpX1,MiddleY-tmpY1);
AreaDraw(&RenderPort,MiddleX+MX,MiddleY-MY);
AreaDraw(&RenderPort,MiddleX+tmpX2,MiddleY-tmpY2);
AreaEnd(&RenderPort);
if (tmpY1 > tmpY2) Pen=WhitePen; else Pen=BlackPen;
if (tmpY1 == tmpY2) {
if (tmpX1 < tmpX2) Pen=WhitePen; else Pen=BlackPen;
}
SetAPen(&RenderPort,Pen);
Move(&RenderPort,MiddleX,MiddleY);
Draw(&RenderPort,MiddleX+tmpX1,MiddleY-tmpY1);
Draw(&RenderPort,MiddleX+MX,MiddleY-MY);
if (Pen == BlackPen) Pen=WhitePen; else Pen=BlackPen;
SetAPen(&RenderPort,Pen);
Draw(&RenderPort,MiddleX+tmpX2,MiddleY-tmpY2);
Draw(&RenderPort,MiddleX,MiddleY);
}
}
int main(void)
{
LONG ModeID,ID,i,WinMask,TimeMask,sig,Cols,Address,WBWait;
LONG PixelX,PixelY,ExtraY=0; /* For aspect ratio's sake */
LONG DirFiles=0;
BOOL RUNNING=TRUE,EXIT=FALSE;
Object *MousePointer;
UBYTE **tools,*s,**File,*ex_File[NUMFILES];
struct WBArg *Args=_WBenchMsg->sm_ArgList;
struct ColorRegister *Colours;
struct ColorMap *CMap;
struct BitMapHeader *BMHD;
struct IntuiMessage *imsg;
struct Rectangle ScreenDimensions;
struct TableCol Grey = {(170 << 24), (170 << 24), (170 << 24)};
struct TableCol White = {0xffffffff, 0xffffffff, 0xffffffff};
struct TableCol Black = {0L,0L,0L};
struct TableCol Red = {0xffffffff, 0L, 0L};
struct FileInfoBlock *fib;
UBYTE FileName[NAMESIZE];
struct TagItem *tstate, *tag;
struct TagItem *tags;
ULONG tidata,RandNumber,ex_Ret;
i=DOSBase->dl_lib.lib_Version;
if (i < 39) {
if (i >= 36) Message("This program requires Kickstart V39\nor higher to run.",CANCEL);
exit(40);
}
PictureClock=(struct Process *) FindTask(NULL);
if (PictureClock->pr_CLI) {
Arguments=ReadArgs(TEMPLATE,options,NULL);
if (! Arguments) {
Printf("Usage: PictureClock %s\n",TEMPLATE);
exit(10);
}
} else { // if WB
if (ProgramIcon=GetDiskObject(Args->wa_Name)) {
tools=(UBYTE **) ProgramIcon->do_ToolTypes;
if (_WBenchMsg->sm_NumArgs == 1) {
s=(UBYTE *) FindToolType(tools,"PICTURE");
if (s) options[PICTURE]=(ULONG) s; else {
Message("You have to specify a\npicture file or dir !",CANCEL);
exit(10);
}
} else {
NameFromLock(Args[_WBenchMsg->sm_NumArgs-1].wa_Lock,FileName,NAMESIZE);
AddPart(FileName,Args[_WBenchMsg->sm_NumArgs-1].wa_Name,NAMESIZE);
options[PICTURE]=(ULONG) FileName;
}
s=(UBYTE *) FindToolType(tools,"SOUND");
if (s) options[SOUND]=(ULONG) s;
s=(UBYTE *) FindToolType(tools,"WAITBETWEENSAMPLES");
if (s) {
WBWait=atol(s);
options[WAIT]=(ULONG) &WBWait;
} else if (s=(UBYTE *) FindToolType(tools,"WAIT")) {
WBWait=atol(s);
options[WAIT]=(ULONG) &WBWait;
}
s=(UBYTE *) FindToolType(tools,"NOSEC");
if (s) options[NOSEC]=TRUE;
s=(UBYTE *) FindToolType(tools,"NOTICK");
if (s) options[NOTICK]=TRUE;
s=(UBYTE *) FindToolType(tools,"CONT");
if (s) options[CONT]=TRUE;
s=(UBYTE *) FindToolType(tools,"CONTINUOUS");
if (s) options[CONT]=TRUE;
s=(UBYTE *) FindToolType(tools,"BESTMODEID");
if (s) options[BESTMODEID]=TRUE;
s=(UBYTE *) FindToolType(tools,"SLIM");
if (s) options[SLIM]=TRUE;
}
}
strncpy(FileName,(UBYTE *) options[PICTURE],NAMESIZE);
DataTypesBase=OpenLibrary("datatypes.library",39L);
if (! DataTypesBase) {
Message("Can't open datatypes.library V39 !",CANCEL);
exit(10);
}
if (options[SLIM]) {
HourFactor=.25;
MinFactor=.6;
}
if (options[SOUND]) {
Sound=NewDTObject((APTR) options[SOUND],
DTA_GroupID, GID_SOUND,
SDTA_Volume, 64,
SDTA_Cycles, 1,
TAG_DONE);
if (Sound) {
Beieraar=CreateNewProcTags( NP_Entry, BeierDeBeier,
NP_StackSize, 1024,
NP_Priority, -2,
NP_Output, Open("CON:11/11/320/80/Beieraar/AUTO/WAIT",MODE_NEWFILE),
NP_Name, SoundProcName,
TAG_DONE);
} else {
if (! Message("Can't open %s as a sound sample file !\nDo you wish to continue anyway ?",OKCAN,options[SOUND]))
exit(0);
}
}
if (! (Handle=Lock(FileName,SHARED_LOCK))) {
Message("Can't find %s !",CANCEL,FileName);
exit(20);
}
fib=AllocDosObject(DOS_FIB,NULL);
if (! fib) {
Message("Can't allocate FileInfoBlock !",CANCEL);
UnLock(Handle);
exit(20);
} else {
Examine(Handle,fib);
if (fib->fib_DirEntryType > 0) { // is a dir
File=AllocMem(MAXFILES*sizeof(UBYTE *),MEMF_CLEAR);
if (! File) {
Message("Out of memory !",CANCEL);
UnLock(Handle);
FreeDosObject(DOS_FIB,(void *) fib);
exit(20);
}
while(ex_Ret=ExAllDoesntWorkAtAll(Handle,fib,ex_File,NUMFILES,NAMESIZE)) {
for(i=0; i<ex_Ret; i++) {
if (DirFiles < MAXFILES) {
File[DirFiles]=AllocMem(NAMESIZE,MEMF_CLEAR);
if (File[DirFiles]) {
strncpy(File[DirFiles],ex_File[i],NAMESIZE);
FreeMem(ex_File[i],NAMESIZE);
DirFiles++;
}
}
}
}
if (IoErr() != ERROR_NO_MORE_ENTRIES) {
Message("ExAllDoesntWorkAtAll() failed with\nDOS error code #%ld",CANCEL,IoErr());
for(i=0; i<DirFiles; i++)
if (File[i]) FreeMem(File[i],NAMESIZE);
FreeMem(File,MAXFILES*sizeof(UBYTE *));
exit(20);
}
if (DirFiles == 0) {
Message("Directory\n%s\ncontains no picture files.",CANCEL,FileName);
FreeMem(File,MAXFILES*sizeof(UBYTE *));
exit(10);
}
/* Get a random number the Murty Termoes way :-) */
do {
srand(custom.vhposr);
{ rand(); rand(); rand(); }
RandNumber=(rand() * DirFiles)/MAX_LONG;
} while (RandNumber >= DirFiles);
strncpy(FileName,File[RandNumber],NAMESIZE);
for(i=0; i<DirFiles; i++)
if (File[i]) FreeMem(File[i],NAMESIZE);
FreeMem(File,MAXFILES*sizeof(UBYTE *));
}
}
FreeDosObject(DOS_FIB,(void *) fib);
atexit(CleanUp);
Table=(struct LoadRGB32Table *) AllocMem(sizeof(struct LoadRGB32Table),MEMF_CLEAR);
if (! Table) exit(20);
TimePort=CreateMsgPort();
if (! TimePort) {
Message("Can't open MsgPort for timer.device !",CANCEL);
exit(20);
} else TimeMask=(1L << TimePort->mp_SigBit);
TimerRequest.tr_node.io_Message.mn_ReplyPort=TimePort;
TimerRequest.tr_node.io_Command=TR_ADDREQUEST;
TimerRequest.tr_time.tv_secs=1L;
if (OpenDevice(TIMERNAME,UNIT_WAITUNTIL,(struct IORequest *) &TimerRequest,0L)) {
Message("Can't open timer.device !",CANCEL);
exit(25);
} else {
TimerBase=(struct Library *) TimerRequest.tr_node.io_Device;
/* Send the request now, when the picture is there, we can draw
the clock straight away. */
SendIO((struct IORequest *) &TimerRequest);
}
InputPort=CreateMsgPort();
if (! InputPort) {
Message("Can't open MsgPort for input.device !",CANCEL);
exit(20);
}
InputReq.io_Message.mn_ReplyPort=InputPort;
InputReq.io_Command=IND_WRITEEVENT;
InputReq.io_Flags=IOF_QUICK;
InputReq.io_Length=sizeof(struct InputEvent);
InputReq.io_Data=&KeyPress;
if (OpenDevice("input.device",0,(struct IORequest *) &InputReq,0)) {
Message("Can't open input.device !",CANCEL);
exit(20);
}
Picture=NewDTObject((APTR) FileName,
DTA_GroupID, GID_PICTURE,
PDTA_Remap, FALSE,
TAG_DONE);
UnLock(Handle);
if (! Picture) {
Message("datatypes.library error #%ld",CANCEL,IoErr());
exit(20);
}
GetDTAttrs(Picture, PDTA_ModeID, &ModeID,
PDTA_BitMapHeader, &BMHD,
PDTA_ColorRegisters, &Address,
PDTA_NumColors, &Cols,
TAG_DONE);
if (options[BESTMODEID]) {
ID=BestModeID( BIDTAG_DIPFMustNotHave, DIPF_IS_HAM,
BIDTAG_DesiredWidth, BMHD->bmh_Width,
BIDTAG_DesiredHeight, BMHD->bmh_Height,
BIDTAG_Depth, BMHD->bmh_Depth,
TAG_DONE);
if (ID == INVALID_ID) {
if (! Message("BestModeID() couldn't come up with anything.\nUse the picture's default ModeID ?",OKCAN)) exit(0);
} else {
ModeID=ID;
}
}
{
if (ModeID & HAM) {
Message("Sorry, HAM pictures are not supported.",OKAY);
exit(0);
}
Table->NumCols=Cols;
for(i=0; i<Cols; i++) {
Colours=(struct ColorRegister *) (Address + i * sizeof(struct ColorRegister));
Table->Registers[i].Red=Colours->red << 24;
Table->Registers[i].Green=Colours->green << 24;
Table->Registers[i].Blue=Colours->blue << 24;
}
}
Workbench=CloseWorkBench();
/* Get standard overscan dimensions */
QueryOverscan(ModeID,&ScreenDimensions,OSCAN_STANDARD);
PixelX=X=ScreenDimensions.MaxX - ScreenDimensions.MinX + 1;
PixelY=Y=ScreenDimensions.MaxY - ScreenDimensions.MinY + 1;
if (X > BMHD->bmh_Width) {
ScreenDimensions.MinX=(X-BMHD->bmh_Width)/2;
ScreenDimensions.MaxX=ScreenDimensions.MinX + BMHD->bmh_Width;
}
if (Y > BMHD->bmh_Height) {
TopOffset=(Y-BMHD->bmh_Height)/2;
ScreenDimensions.MaxY=BMHD->bmh_Height + TopOffset;
} else TopOffset=0;
/* Now calculate the new screen dimemsions and open the screen */
X=ScreenDimensions.MaxX - ScreenDimensions.MinX + 1;
Y=ScreenDimensions.MaxY - ScreenDimensions.MinY + 1;
MyScreen=OpenScreenTags(NULL, SA_Left, ScreenDimensions.MinX,
SA_Top, ScreenDimensions.MinY,
SA_Width, X,
SA_Height, Y,
SA_Depth, BMHD->bmh_Depth,
SA_Type, CUSTOMSCREEN,
SA_DisplayID, ModeID,
SA_ShowTitle, FALSE,
SA_DClip, &ScreenDimensions,
SA_Colors32, Table,
TAG_DONE);
if (! MyScreen) {
Message("OpenScreen() failed",CANCEL);
exit(20);
} else CMap=MyScreen->ViewPort.ColorMap;
DoubleBuffer=AllocDBufInfo(&MyScreen->ViewPort);
if (! DoubleBuffer) {
Message("Can't allocate DoubleBuffer info !",CANCEL);
exit(20);
} else {
BufferPort[0]=CreateMsgPort();
BufferPort[1]=CreateMsgPort();
if (! (BufferPort[0] && BufferPort[1])) {
Message("Can't allocate MsgPort(s) !",CANCEL);
exit(20);
}
DoubleBuffer->dbi_SafeMessage.mn_ReplyPort=BufferPort[0];
DoubleBuffer->dbi_DispMessage.mn_ReplyPort=BufferPort[1];
}
Front=OpenWindowTags(NULL, WA_Left, 0,
WA_Top, 0,
WA_Width, MyScreen->Width,
WA_Height, MyScreen->Height,
WA_IDCMP, IDCMP_IDCMPUPDATE|IDCMP_MOUSEBUTTONS,
WA_CustomScreen, MyScreen,
WA_SimpleRefresh, TRUE,
WA_Borderless, TRUE,
WA_BusyPointer, TRUE,
WA_RMBTrap, TRUE,
WA_Activate, TRUE,
TAG_DONE);
if (! Front) {
Message("Can't open window !",CANCEL);
exit(20);
} else {
WinMask=1L << Front->UserPort->mp_SigBit;
BufferMap[B_SHOW]=Front->RPort->BitMap;
MiddleX=Front->Width/2;
MiddleY=(Front->Height + TopOffset)/2;
}
BufferMap[B_RENDER]=AllocBitMap(MyScreen->Width,MyScreen->Height,BMHD->bmh_Depth,BMF_CLEAR|BMF_DISPLAYABLE,NULL);
if (! BufferMap[B_RENDER]) {
Message("Can't allocate DoubleBuffer BitMap !",CANCEL);
exit(20);
} else {
BufferMap[B_FREE]=BufferMap[B_RENDER];
TempRaster=AllocRaster(MiddleX,MiddleY);
if (! TempRaster) {
Message("Can't allocate raster memory !",CANCEL);
exit(20);
}
InitArea(&ar_Info,AreaData,10);
InitTmpRas(&ar_Raster,TempRaster,RASSIZE(MiddleX,MiddleY));
InitRastPort(&RenderPort);
RenderPort.BitMap=BufferMap[B_RENDER];
RenderPort.AreaInfo=&ar_Info;
RenderPort.TmpRas=&ar_Raster;
}
ExtraMap=AllocBitMap(Front->Width,Front->Height,BMHD->bmh_Depth,0,NULL);
if (! ExtraMap) {
Message("Can't allocate extra BitMap !",CANCEL);
exit(20);
}
SetDTAttrs(Picture,NULL,NULL, GA_Left, 0,
GA_Top, TopOffset,
GA_Width, Front->Width,
GA_Height, Front->Height - TopOffset,
ICA_TARGET, ICTARGET_IDCMP,
TAG_DONE);
AddDTObject(Front,NULL,Picture,-1L);
RefreshDTObjects(Picture,Front,NULL,NULL);
while(RUNNING) {
sig=Wait(WinMask | SIGBREAKF_CTRL_C);
if (sig & SIGBREAKF_CTRL_C) { RUNNING=FALSE; EXIT=TRUE; }
while (imsg = (struct IntuiMessage *) GetMsg (Front->UserPort)) {
switch (imsg->Class)
{
case IDCMP_IDCMPUPDATE:
tstate = tags = (struct TagItem *) imsg->IAddress;
while (tag = NextTagItem (&tstate))
{
tidata = tag->ti_Data;
switch (tag->ti_Tag)
{
case DTA_Busy:
if (tidata)
SetWindowPointer (Front, WA_BusyPointer, TRUE, TAG_DONE);
else
SetWindowPointer (Front, WA_Pointer, NULL, TAG_DONE);
break;
case DTA_Sync:
RefreshDTObjects (Picture, Front, NULL, NULL);
RUNNING=FALSE;
break;
}
}
break;
}
/* Done with the message, so reply to it */
ReplyMsg ((struct Message *) imsg);
}
}
RemoveDTObject(Front,Picture);
DisposeDTObject(Picture);
Picture=NULL;
if (EXIT) exit(0);
MousePointer=NewObject(NULL,POINTERCLASS,
POINTERA_BitMap, BufferMap[B_FREE],
POINTERA_WordWidth, 1L,
TAG_DONE);
if (MousePointer) SetWindowPointer(Front,WA_Pointer,MousePointer,TAG_DONE);
GreyPen=FindColor(CMap,Grey.Red,Grey.Green,Grey.Blue,Cols);
WhitePen=FindColor(CMap,White.Red,White.Green,White.Blue,Cols);
BlackPen=FindColor(CMap,Black.Red,Black.Green,Black.Blue,Cols);
RedPen=FindColor(CMap,Red.Red,Red.Green,Red.Blue,Cols);
SetAPen(Front->RPort,GreyPen);
SetDrMd(Front->RPort,JAM1);
if ((Front->Height - TopOffset) > Front->Width)
ExtraY=(Front->Height - TopOffset - Front->Width)/2;
/* 12 o' clock */
{
tmpX1=(40 * PixelX)/700;
tmpX2=tmpX1/2;
Left=(Front->Width-tmpX1-5)/2;
Right=Front->Width-Left;
Top=TopOffset + ExtraY + ((5 * PixelX)/300);
Bottom=Front->Height - ExtraY - ((5 * PixelX)/300);
RadiusY=(Bottom-Top)/2;
RadiusX=RadiusY * (PixelX/PixelY);
Bottom=Top + (RadiusY / 3);
RectFill(Front->RPort,Left,Top,Right-tmpX2-5,Bottom);
RectFill(Front->RPort,Left+tmpX2+5,Top,Right,Bottom);
SetAPen(Front->RPort,WhitePen);
Move(Front->RPort,Left,Bottom);
Draw(Front->RPort,Left,Top);
Draw(Front->RPort,Left+tmpX2,Top);
SetAPen(Front->RPort,BlackPen);
Draw(Front->RPort,Left+tmpX2,Bottom);
Draw(Front->RPort,Left+1,Bottom);
SetAPen(Front->RPort,WhitePen);
Move(Front->RPort,Left+tmpX2+5,Bottom);
Draw(Front->RPort,Left+tmpX2+5,Top);
Draw(Front->RPort,Left+tmpX1+5,Top);
SetAPen(Front->RPort,BlackPen);
Draw(Front->RPort,Left+tmpX1+5,Bottom);
Draw(Front->RPort,Left+tmpX2+5+1,Bottom);
}
/* 6 o' clock */
{
Left=(Front->Width-tmpX2)/2;
Right=Front->Width-Left;
Bottom=Front->Height - ExtraY - ((5 * PixelX)/300);
Top=Bottom-(RadiusY / 3);
SetAPen(Front->RPort,GreyPen);
RectFill(Front->RPort,Left,Top,Right,Bottom);
SetAPen(Front->RPort,WhitePen);
Move(Front->RPort,Left,Bottom);
Draw(Front->RPort,Left,Top);
Draw(Front->RPort,Right,Top);
SetAPen(Front->RPort,BlackPen);
Draw(Front->RPort,Right,Bottom);
Draw(Front->RPort,Left+1,Bottom);
}
/* 3 o' clock */
{
Top=MiddleY - ((8 * PixelY)/500);
Bottom=Top + ((16 * PixelY)/500);
Right=MiddleX + RadiusX;
Left=Right - (RadiusX/3);
SetAPen(Front->RPort,GreyPen);
RectFill(Front->RPort,Left,Top,Right,Bottom);
SetAPen(Front->RPort,WhitePen);
Move(Front->RPort,Left,Bottom);
Draw(Front->RPort,Left,Top);
Draw(Front->RPort,Right,Top);
SetAPen(Front->RPort,BlackPen);
Draw(Front->RPort,Right,Bottom);
Draw(Front->RPort,Left+1,Bottom);
}
/* 9 o' clock */
{
Left=MiddleX - RadiusX;
Right=Left + (RadiusX/3);
SetAPen(Front->RPort,GreyPen);
RectFill(Front->RPort,Left,Top,Right,Bottom);
SetAPen(Front->RPort,WhitePen);
Move(Front->RPort,Left,Bottom);
Draw(Front->RPort,Left,Top);
Draw(Front->RPort,Right,Top);
SetAPen(Front->RPort,BlackPen);
Draw(Front->RPort,Right,Bottom);
Draw(Front->RPort,Left+1,Bottom);
}
BltBitMap(Front->RPort->BitMap,0,0,ExtraMap,0,0,Front->Width,Front->Height,0x0C0,0xff,NULL);
BltBitMap(Front->RPort->BitMap,0,0,BufferMap[B_RENDER],0,0,Front->Width,Front->Height,0x0C0,0xff,NULL);
WaitBlit();
RUNNING=TRUE;
HRX=(RadiusX * 2)/3;
HRY=(RadiusY * 2)/3;
tmpRX=RadiusX / 2;
tmpRY=RadiusY / 2;
while(RUNNING) {
sig=Wait(TimeMask | WinMask | SIGBREAKF_CTRL_C);
if (sig & SIGBREAKF_CTRL_C) RUNNING=FALSE;
if (sig & WinMask && RUNNING) {
while (imsg = (struct IntuiMessage *) GetMsg (Front->UserPort)) {
switch (imsg->Class)
{
case IDCMP_MOUSEBUTTONS : RUNNING=FALSE;
break;
}
/* Done with the message, so reply to it */
ReplyMsg ((struct Message *) imsg);
}
}
if (sig & TimeMask && RUNNING) {
GetSysTime(&TimerRequest.tr_time);
Amiga2Date(TimerRequest.tr_time.tv_secs,&CurrTime);
TimerRequest.tr_time.tv_secs+=1L;
SendIO((struct IORequest *) &TimerRequest);
/* Calculate all the new values */
{
Sec=CurrTime.sec;
Min=CurrTime.min;
Hour=(CurrTime.hour > 12) ? CurrTime.hour-12 : CurrTime.hour;
if (Sec==0) {
TimeCount=0;
if (Min==30) Beierink=1;
if (Min==0) Beierink=Hour;
}
if (options[CONT]) Min+=(Sec/60);
Hour+=(Min/60);
angle=(Sec/60) * 2 * PI; /* Angle in radials */
mangle=(Min/60) * 2 * PI;
hangle=(Hour/12) * 2 * PI;
X=(LONG) (sin(angle) * RadiusX);
Y=(LONG) (cos(angle) * RadiusY);
MX=(LONG) (sin(mangle) * RadiusX);
MY=(LONG) (cos(mangle) * RadiusY);
HX=(LONG) (sin(hangle) * HRX);
HY=(LONG) (cos(hangle) * HRY);
}
if (! options[NOTICK]) {
/* Simulate a keypress, the left shift in this case.
Together with Yak, this makes a nice, ticking sound. */
memset(&KeyPress,0,sizeof(struct InputEvent));
KeyPress.ie_Class=IECLASS_RAWKEY;
KeyPress.ie_Code=SHIFT;
DoIO((struct IORequest *) &InputReq);
/* And up again */
memset(&KeyPress,0,sizeof(struct InputEvent));
KeyPress.ie_Class=IECLASS_RAWKEY;
KeyPress.ie_Code=SHIFT | IECODE_UP_PREFIX;
DoIO((struct IORequest *) &InputReq);
}
if (Beieraar && Beierink) {
Signal((struct Task *) Beieraar,SIGBREAKF_CTRL_F);
}
DrawArms(); /* Draw minute and hour hands */
if (! options[NOSEC]) {
SetAPen(&RenderPort,RedPen);
Move(&RenderPort,MiddleX,MiddleY);
Draw(&RenderPort,MiddleX+X,MiddleY-Y);
}
ChangeVPBitMap(&MyScreen->ViewPort,BufferMap[B_RENDER],DoubleBuffer);
/* Wait until it is safe to write to the BitMap */
while(! GetMsg(DoubleBuffer->dbi_SafeMessage.mn_ReplyPort))
Wait(1L << (DoubleBuffer->dbi_SafeMessage.mn_ReplyPort->mp_SigBit));
BufferMap[B_SWAP]=BufferMap[B_SHOW];
BufferMap[B_SHOW]=BufferMap[B_RENDER];
BufferMap[B_RENDER]=BufferMap[B_SWAP];
RenderPort.BitMap=BufferMap[B_RENDER];
BltBitMap(ExtraMap,0,0,BufferMap[B_RENDER],0,0,Front->Width,Front->Height,0x0C0,0xff,NULL);
/* Wait until it is safe to swap the BitMaps, then you won't
have to do it next time around. */
while(! GetMsg(DoubleBuffer->dbi_DispMessage.mn_ReplyPort))
Wait(1L << (DoubleBuffer->dbi_DispMessage.mn_ReplyPort->mp_SigBit));
}
}
if (MousePointer) {
DisposeObject(MousePointer);
SetWindowPointer(Front,WA_Pointer,NULL,TAG_DONE);
}
exit(0);
}